package org.aceor.mddal.common.zk.config;

import com.google.common.base.Objects;
import com.google.common.base.Strings;
import org.aceor.mddal.common.constants.Constants;
import org.aceor.mddal.common.enums.ErrorCodeEnum;
import org.aceor.mddal.common.exception.BusinessRuntimeException;
import org.aceor.mddal.common.utils.ValidateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

/**
 * Created by lxue on 16/3/19.
 */
public class ConfigLoader {

    private static final Logger logger = LoggerFactory.getLogger(ConfigLoader.class);

    private static final String DEFAULT_ZK_PROPERTIES_LOCATION = "/zk.properties";
    private static String zkIp;
    private static String zkDomain;
    private static String clientPort;
    private static Integer maxRetries;
    private static Integer baseSleepTime;
    private static Integer sessionTimeout;

    static {
        Properties prop = new Properties();
        InputStream is = ConfigLoader.class.getResourceAsStream(DEFAULT_ZK_PROPERTIES_LOCATION);
        try {
            prop.load(is);
            zkIp = prop.getProperty("zk.ip");
            zkDomain = fillDefaultStrValueIfNullOrEmpty(prop.getProperty("zk.domain"), Constants.DEFAULT_ZK_DOMAIN_NAME);
            clientPort = fillDefaultStrValueIfNullOrEmpty(prop.getProperty("zk.client.port"), Constants.DEFAULT_ZK_CLIENT_PORT);
            maxRetries = fillDefaultIntValueIfNullOrEmpty(prop.getProperty("zk.max.retries"), Constants.DEFAULT_ZK_MAX_RETRIES);
            baseSleepTime = fillDefaultIntValueIfNullOrEmpty(prop.getProperty("zk.base.sleep.time"), Constants.DEFAULT_ZK_BASE_SLEEP_TIME);
            sessionTimeout = fillDefaultIntValueIfNullOrEmpty(prop.getProperty("zk.session.timeout"), Constants.DEFAULT_ZK_SESSION_TIMEOUT);
            checkHasOneNotEmpty(zkIp,zkDomain);
            checkAllNotEnmpty(clientPort,maxRetries,baseSleepTime,sessionTimeout);
        } catch (IOException e) {
            throw new BusinessRuntimeException("zk配置文件解析失败", e);
        }
    }

    private static String fillDefaultStrValueIfNullOrEmpty(String originValue, String defaultValue) {
        return Strings.isNullOrEmpty(originValue) ? defaultValue : originValue;
    }

    private static Integer fillDefaultIntValueIfNullOrEmpty(String originValue, Integer defaultValue) {
        return Strings.isNullOrEmpty(originValue) ? defaultValue : Integer.valueOf(originValue);
    }
    public static String getZkIp() {
        return zkIp;
    }

    public static String getZkDomain() {
        return zkDomain;
    }

    public static Integer getMaxRetries() {
        return maxRetries;
    }

    public static Integer getSessionTimeout() {
        return sessionTimeout;
    }

    public static String getClientPort() {
        return clientPort;
    }

    public static Integer getBaseSleepTime() {
        return baseSleepTime;
    }

    public static String getConnectString() {
        //配置了ip的话,优先使用ip;否则使用域名(这个需要在hosts文件中配置指向zkServerIp)
        if (!Strings.isNullOrEmpty(zkIp)) {
            return zkIp + ":" + clientPort;
        } else {
            return zkDomain + ":" + clientPort;
        }
    }

    public static void checkHasOneNotEmpty(Object... params) {
        if (null == params) {
            throw new BusinessRuntimeException(ErrorCodeEnum.PARAM_ERROR);
        }
        boolean result = false;
        for (Object param : params) {
            result = result || !ValidateUtil.isNullOrEmpty(param);
            //只要为true,就检验通过
            if (result) {
                return;
            }
        }
        logger.error("ConfigLoader$zk part propertity null or empty all ==> " +
                "zkIp={},zkDomain={}",params);
        throw new BusinessRuntimeException(ErrorCodeEnum.ZKCONFIG_PART_PROPERTITY_ALL_NULLOREMPTY);
    }

    public static void checkAllNotEnmpty(Object... params) {
        if (null == params) {
            throw new BusinessRuntimeException(ErrorCodeEnum.PARAM_ERROR);
        }
        for (Object param : params) {
            if (ValidateUtil.isNullOrEmpty(param)) {
                logger.error("ConfigLoader$zk part propertity exsit null or empty ==> " +
                        "clientPort={},maxRetries={},baseSleepTime={},sessionTimeout={}",params);
                throw new BusinessRuntimeException(ErrorCodeEnum.ZKCONFIG_PART_PROPERTITY_EXSIT_NULLOREMPTY);
            }
        }
    }

    @Override
    public String toString() {
        return Objects.toStringHelper(this)
                .add("zkIp",zkIp)
                .add("zkDomain",zkDomain)
                .add("clientPort",clientPort)
                .add("sessionTimeout",sessionTimeout)
                .add("maxRetries",maxRetries)
                .add("baseSleepTime",baseSleepTime)
                .toString();
    }

    public static void main(String[] args){
        System.out.println(new ConfigLoader().toString());
    }
}
